组合和选择

  将组合(通过使用指令)和选择(通过使用声明)结合起来能产生更多的灵活性,这些也都是真实世界的例子所需要的。依靠这些机制,我们就能有这样的方式,它们既能提供对许多机制的访问,又能消解由于组合而产生的名字冲突或者歧义性。看例子,

    namespace His_lib {
        class String { /* ... */ };
        template<class T> class Vector { /* ... */ };
        // ...
    }
    namespace Her_vector {
        template<class T> class Vector { /* ... */ };
        // ...
    }

    namespace My_lib {
        using namespace His_lib;        // 来自His_lib的所有东西
        using namespace Her_lib;        // 来自Her_lib的所有东西

        using His_lib::String;          // 以偏向His_lib的方式解析潜在的冲突
        using Her_lib::Vector;          // 以偏向Her_lib的方式解析潜在的冲突

        template<class T> class List { /* ... */ };    // 增加的东西
        // ...
    }

在查看一个名字空间时,其中显式声明的名字(包括通过使用声明声明的名字)优先于在其他作用域里的那些通过使用指令才能访问的名字(C.10.1节)。这样,My_lib的用户将会看到,对于String和Vector名字冲突的解析将分别偏向于His_lib::Strng和Her_lib::Vector。还有,My_lib::List将总会被使用,与His_lib或Her_lib是否提供了List完全没关系。

  通常,在将一个名字引进一个新的名字空间时,我最喜欢让它保持不变。按照这种方式,我就不必去记住两个不同的名字实际上指的是同一个东西。当然,有时确实也会需要新名字,或者是用新的更好。例如,

    namespace Lib2 {
        using namespace His_lib;        // 来自His_lib的所有东西
        using namespace Her_lib;        // 来自Her_lib的所有东西

        using His_lib::String;          // 以偏向His_lib的方式解析潜在的冲突
        using Her_lib::Vector;          // 以偏向Her_lib的方式解析潜在的冲突

        typedef Her_lib::String her_string;        // 重命名

        template<class T> class His_vec            // "重命名"
            : public His_lib::Vector<T> { /* ... */ };

        template<class T> class List { /* ... */ };    // 增加的东西
        // ...
    }

这里不存在专用于重命名的特定语言机制,使用的是定义新实体的通用机制。

🔚